home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH16 / NUMBERS.ASM < prev    next >
Encoding:
Assembly Source File  |  1994-07-10  |  7.5 KB  |  361 lines

  1. ; Numbers.asm
  2. ;
  3. ; This program converts written English numbers in the range "zero"
  4. ; to "sixty five thousand five hundred thirty five" to the corresponding
  5. ; integer value.
  6.  
  7.         .xlist
  8.         include     stdlib.a
  9.         includelib    stdlib.lib
  10.         matchfuncs
  11.         .list
  12.  
  13.  
  14. dseg        segment    para public 'data'
  15.  
  16. Value        word    0            ;Store results here.
  17. HundredsVal    word    0
  18. ThousandsVal    word    0
  19.  
  20.  
  21. Str0        byte    "twenty one",0
  22. Str1        byte    "nineteen hundred thirty-five",0
  23. Str2        byte    "thirty three thousand two hundred nineteen",0
  24. Str3        byte    "three",0
  25. Str4        byte    "fourteen",0
  26. Str5        byte    "fifty two",0
  27. Str6        byte    "seven hundred",0
  28. Str7        byte    "two thousand seven",0
  29. Str8        byte    "four thousand ninety six",0
  30. Str9        byte    "five hundred twelve",0
  31. Str10        byte    "twenty three thousand two hundred ninety-five",0
  32. Str11        byte    "seventy-five hundred",0
  33. Str12        byte    "sixty-five thousand",0
  34. Str13        byte    "one thousand",0
  35.  
  36.  
  37. ; The following grammar is what we use to process the numbers.
  38. ; Semantic actions appear in the braces.
  39. ;
  40. ; Note: begin by initializing Value, HundredsVal, and ThousandsVal to zero.
  41. ;
  42. ; N        -> separators zero
  43. ;        |  N4
  44. ;
  45. ; N4        -> do1000s maybe100s
  46. ;        |  do100s
  47. ;
  48. ; Maybe100s     -> do100s
  49. ;        |  <empty string>
  50. ;
  51. ; do1000s    -> Under100 "THOUSAND" separators
  52. ;                {ThousandsVal := Value*1000}
  53. ;
  54. ; do100s    -> Under100 "HUNDRED"
  55. ;            {HundredsVal := Value*100} After100
  56. ;        |  Under100
  57. ;
  58. ; After100    -> {Value := 0} Under100
  59. ;        |  {Value := 0} <empty string>
  60. ;
  61. ; Under100    -> {Value := 0} try20 try1s
  62. ;        |  {Value := 0} doTeens
  63. ;        |  {Value := 0} do1s
  64. ;
  65. ; try1s        -> do1s | <empty string>
  66. ;
  67. ; try20        -> "TWENTY" {Value := Value + 20}
  68. ;        |  "THIRTY" {Value := Value + 30}
  69. ;        |  ...
  70. ;        |  "NINETY" {Value := Value + 90}
  71. ;
  72. ; doTeens    -> "TEN"     {Value := Value + 10}
  73. ;        |  "ELEVEN"     {Value := Value + 11}
  74. ;        |  ...
  75. ;        |  "NINETEEN"     {Value := Value + 19}
  76. ;
  77. ; do1s        -> "ONE"    {Value := Value + 1}
  78. ;        |  "TWO"    {Value := Value + 2}
  79. ;        |  ...
  80. ;        |  "NINE"    {Value := Value + 9}
  81.  
  82.  
  83. separators    pattern    {anycset, delimiters, 0, delim2}
  84. delim2        pattern    {spancset, delimiters}
  85. doSuccess    pattern    {succeed}
  86. AtLast        pattern    {sl_match2, separators, AtEOS, AtEOS}
  87. AtEOS        pattern    {EOS}
  88.  
  89.  
  90. N        pattern    {sl_match2, separators, N2, N2}
  91. N2        pattern    {matchistr, zero, N3, AtLast}
  92. zero        byte    "ZERO",0
  93.  
  94. N3        pattern    {sl_match2, N4, 0, AtLast}
  95. N4        pattern    {sl_match2, do1000s, do100s, Maybe100s}
  96. Maybe100s    pattern    {sl_match2, do100s, AtLast, AtLast}
  97.  
  98. do1000s        pattern    {sl_match2, Under100, 0, do1000s2}
  99. do1000s2    pattern    {matchistr, str1000, 0, do1000s3}
  100. do1000s3    pattern    {sl_match2, separators, do1000s4, do1000s5}
  101. do1000s4    pattern    {EOS, 0, 0, do1000s5}
  102. do1000s5    pattern    {Get1000s}
  103. str1000        byte    "THOUSAND",0
  104.  
  105. do100s        pattern    {sl_match2, do100s1, Under100, After100}
  106. do100s1        pattern    {sl_match2, Under100, 0, do100s2}
  107. do100s2        pattern    {matchistr, str100, 0, do100s3}
  108. do100s3        pattern    {sl_match2, separators, do100s4, do100s5}
  109. do100s4        pattern    {EOS, 0, 0, do100s5}
  110. do100s5        pattern    {Get100s}
  111. str100        byte    "HUNDRED",0
  112.  
  113. After100    pattern    {SetVal, 0, 0, After100a}
  114. After100a    pattern    {sl_match2, Under100, doSuccess}
  115.  
  116. Under100    pattern    {SetVal, 0, 0, Under100a}
  117. Under100a    pattern    {sl_match2, try20, Under100b, Do1orE}
  118. Under100b    pattern    {sl_match2, doTeens, do1s}
  119.  
  120. Do1orE        pattern    {sl_match2, do1s, doSuccess, 0}
  121.  
  122.  
  123.  
  124. NumPat        macro    lbl, next, Constant, string
  125.         local    try, SkipSpcs, val, str, tryEOS
  126. lbl        pattern    {sl_match2, try, next}
  127. try        pattern    {matchistr, str, 0, SkipSpcs}
  128. SkipSpcs    pattern    {sl_match2, separators, tryEOS, val}
  129. tryEOS        pattern    {EOS, 0, 0, val}
  130. val        pattern    {AddVal, Constant}
  131. str        byte    string
  132.         byte    0
  133.         endm
  134.  
  135.         NumPat    doTeens, try11, 10, "TEN"
  136.         NumPat    try11, try12, 11, "ELEVEN"
  137.         NumPat    try12, try13, 12, "TWELVE"
  138.         NumPat    try13, try14, 13, "THIRTEEN"
  139.         NumPat    try14, try15, 14, "FOURTEEN"
  140.         NumPat    try15, try16, 15, "FIFTEEN"
  141.         NumPat    try16, try17, 16, "SIXTEEN"
  142.         NumPat    try17, try18, 17, "SEVENTEEN"
  143.         NumPat    try18, try19, 18, "EIGHTEEN"
  144.         NumPat    try19, 0, 19, "NINETEEN"
  145.  
  146.         NumPat    do1s, try2, 1, "ONE"
  147.         NumPat    try2, try3, 2, "TWO"
  148.         NumPat    try3, try4, 3, "THREE"
  149.         NumPat    try4, try5, 4, "FOUR"
  150.         NumPat    try5, try6, 5, "FIVE"
  151.         NumPat    try6, try7, 6, "SIX"
  152.         NumPat    try7, try8, 7, "SEVEN"
  153.         NumPat    try8, try9, 8, "EIGHT"
  154.         NumPat    try9, 0, 9, "NINE"
  155.  
  156.         NumPat    try20, try30, 20, "TWENTY"
  157.         NumPat    try30, try40, 30, "THIRTY"
  158.         NumPat    try40, try50, 40, "FORTY"
  159.         NumPat    try50, try60, 50, "FIFTY"
  160.         NumPat    try60, try70, 60, "SIXTY"
  161.         NumPat    try70, try80, 70, "SEVENTY"
  162.         NumPat    try80, try90, 80, "EIGHTY"
  163.         NumPat    try90, 0, 90, "NINETY"
  164.  
  165.         include    stdsets.a
  166.  
  167. dseg        ends
  168.  
  169.  
  170.  
  171. cseg        segment    para public 'code'
  172.         assume    cs:cseg, ds:dseg
  173.  
  174.  
  175. ; Semantic actions for our grammar:
  176. ;
  177. ;
  178. ;
  179. ; Get1000s-    We've just processed the value one..nine, grab it from
  180. ;        the value variable, multiply it by 1000, and store it
  181. ;        into thousandsval.
  182.  
  183. Get1000s    proc    far
  184.         push    ds
  185.         push    dx
  186.         mov    ax, dseg
  187.         mov    ds, ax
  188.  
  189.         mov    ax, 1000
  190.         mul    Value
  191.         mov    ThousandsVal, ax
  192.         mov    Value, 0
  193.  
  194.         pop    dx
  195.         mov    ax, di            ;Required by sl_match.
  196.         pop    ds
  197.         stc                ;Always return success.
  198.         ret
  199. Get1000s    endp
  200.  
  201.  
  202. ; Get100s-    We've just processed the value one..nine, grab it from
  203. ;        the value variable, multiply it by 100, and store it
  204. ;        into hundredsval.
  205.  
  206. Get100s        proc    far
  207.         push    ds
  208.         push    dx
  209.         mov    ax, dseg
  210.         mov    ds, ax
  211.  
  212.         mov    ax, 100
  213.         mul    Value
  214.         mov    HundredsVal, ax
  215.         mov    Value, 0
  216.  
  217.         pop    dx
  218.         mov    ax, di            ;Required by sl_match.
  219.         pop    ds
  220.         stc                ;Always return success.
  221.         ret
  222. Get100s        endp
  223.  
  224.  
  225. ; SetVal-    This routine sets Value to whatever is in si
  226.  
  227. SetVal        proc    far
  228.         push    ds
  229.         mov    ax, dseg
  230.         mov      ds, ax
  231.         mov    Value, si
  232.         mov    ax, di
  233.         pop    ds
  234.         stc
  235.         ret
  236. SetVal        endp
  237.  
  238. ; AddVal-    This routine sets adds whatever is in si to Value
  239.  
  240. AddVal        proc    far
  241.         push    ds
  242.         mov    ax, dseg
  243.         mov      ds, ax
  244.         add    Value, si
  245.         mov    ax, di
  246.         pop    ds
  247.         stc
  248.         ret
  249. AddVal        endp
  250.  
  251.  
  252. ; Succeed matches the empty string.  In other words, it matches anything
  253. ; and always returns success without eating any characters from the input
  254. ; string.
  255.  
  256. Succeed        proc    far
  257.         mov    ax, di
  258.         stc
  259.         ret
  260. Succeed        endp
  261.  
  262.  
  263. HereIAm        proc    far
  264.         print
  265.         byte    "Here I am:",0
  266.         mov    ax, si
  267.         putu
  268.         putcr
  269.         mov    ax, di
  270.         stc
  271.         ret
  272. HereIam        endp
  273.  
  274. ConvertNumber    proc    near
  275.         mov    value, 0
  276.         mov    HundredsVal, 0
  277.         mov    ThousandsVal, 0
  278.  
  279.         ldxi    N
  280.         xor    cx, cx
  281.         match
  282.         jnc    NoMatch
  283.         mov    al, "'"
  284.         putc
  285.         puts
  286.         print
  287.         byte    "' = ", 0
  288.         mov    ax, ThousandsVal
  289.         add    ax, HundredsVal
  290.         add    ax, Value
  291.         putu
  292.         putcr
  293.         jmp    Done
  294.  
  295. NoMatch:    print
  296.         byte    "Illegal number",cr,lf,0
  297.  
  298. Done:        ret
  299. ConvertNumber    endp
  300.  
  301.  
  302.  
  303. Main        proc
  304.         mov    ax, dseg
  305.         mov    ds, ax
  306.         mov    es, ax
  307.  
  308.         meminit                ;Init memory manager.
  309.  
  310. ; Union in a "-" to the delimiters set because numbers can have
  311. ; dashes in them.
  312.  
  313.         lesi    delimiters
  314.         mov    al, '-'
  315.         addchar
  316.  
  317.  
  318.         lesi    Str0
  319.         call    ConvertNumber
  320.         lesi    Str1
  321.         call    ConvertNumber
  322.         lesi    Str2
  323.         call    ConvertNumber
  324.         lesi    Str3
  325.         call    ConvertNumber
  326.         lesi    Str4
  327.         call    ConvertNumber
  328.         lesi    Str5
  329.         call    ConvertNumber
  330.         lesi    Str6
  331.         call    ConvertNumber
  332.         lesi    Str7
  333.         call    ConvertNumber
  334.         lesi    Str8
  335.         call    ConvertNumber
  336.         lesi    Str9
  337.         call    ConvertNumber
  338.         lesi    Str10
  339.         call    ConvertNumber
  340.         lesi    Str11
  341.         call    ConvertNumber
  342.         lesi    Str12
  343.         call    ConvertNumber
  344.         lesi    Str13
  345.         call    ConvertNumber
  346.  
  347.  
  348. Quit:        ExitPgm
  349. Main        endp
  350.  
  351. cseg        ends
  352.  
  353. sseg        segment    para stack 'stack'
  354. stk        db    1024 dup ("stack   ")
  355. sseg        ends
  356.  
  357. zzzzzzseg    segment    para public 'zzzzzz'
  358. LastBytes    db    16 dup (?)
  359. zzzzzzseg    ends
  360.         end    Main
  361.